package org.mtmi.ui.controls.edits;

import java.util.Collection;

import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.mtmi.ui.M;
import org.mtmi.ui.actions.RetargetableAction;
import org.mtmi.ui.controls.Control;
import org.mtmi.ui.controls.listeners.PopupListener;
import org.mtmi.ui.controls.popups.AbstractButtonPopup;
import org.mtmi.ui.controls.popups.ColorPopup;
import org.mtmi.ui.drawables.ColorDrawable;
import org.mtmi.ui.drawables.IColorDrawable;
import org.mtmi.ui.drawables.IDrawable;
import org.mtmi.ui.scenes.COLOR;
import org.mtmi.ui.scenes.SceneManager;

public abstract class AbstractChooseColorAction extends RetargetableAction
{
	private IColorDrawable image;
	
	public AbstractChooseColorAction() {
		super( PUSH );
	}
	
	/** @return color for current target, null for none */
	protected abstract Color getColor( Control control );
	
	/** when action is run, this method is called, subclasses should apply this to current target */
	protected abstract void setColor( Control control, Color c );

	/** @return color for current target, null for none */
	protected Color getColor() {
		if( target instanceof Control ) {
			return getColor( (Control)target );
		} else {
			Color c=null;
			boolean f=true;
			for( Object o : (Collection<?>)getTarget() ) {
				Color fg = getColor( (Control)o );
				if( f ) {
					c = fg;
					f=false;
				} else {
					if( c==null && fg!=null || c!=null && !c.equals(fg) ) {
						c=null;
						break;
					}
				}
			}
			return c;
		}
	}
	
	
	/** when action is run, this method is called, subclasses should apply this to current target */
	protected void setColor( Color c ) {
		if( target instanceof Control ) {
			setColor( (Control)target, c );
		} else {
			for( Object o : (Collection<?>)target ) {
				setColor( (Control)o, c );
			}
		}
	}
	
	/** @return true if control is handled */
	protected abstract boolean isControlHandled( Control c );
	
	@Override
	/** @return true if c is a control handled, or a list of control handled (see isControlHandled()) */
	public boolean isTargetHandled( Object c ) {
		if( c instanceof Control && isControlHandled( (Control)c ) ) return true;
		if( c instanceof Collection ) {
			Collection<?> l = (Collection<?>)c;
			for( Object o : l ) {
				if( !(o instanceof Control ) || !isControlHandled( (Control)o ) ) return false;
			}
			return l.size()>0;
		}
		return false;
	}
	
	/** create the "image" for action, by default a ColorDrawable */
	protected IColorDrawable createColorDrawable() {
		return new ColorDrawable( null, false );
	}
	
	@Override
	public IDrawable getImage() {
		if( image==null ) {
			image = createColorDrawable();
		}
		Color c = getColor();
		if( c==null ) c = COLOR.grey50; //image require a color
		image.setColor( c );
		return image;
	}

	@Override
	public boolean isEnabled() {
		return true;
	}
	
	@Override
	public void run() {
		final ColorPopup p = new ColorPopup( SceneManager.getDefault().getScene(), "Choose Color:", M.SCENE_EDITOR_CONTROL );
		Color c = getColor();
		if( c!=null ) {
			p.setRGB( c.getRGB() );
		}
		p.addResponseListener( new PopupListener() {
			@Override
			public void popupButtonSelected(int id) {
				if( id == AbstractButtonPopup.OK ) {
					RGB rgb = p.getRGB();
//TODO: this color should be disposed ... register it in color manager ?					
					Color c = new Color( p.getScene().getDisplay(), rgb );
					setColor( c );
				}
			}
		});
		
	}
	
}